import { ref, computed, watch, readonly } from 'vue'
import type { Ref } from 'vue'

/**
 * 底部动画控制Composable
 * 提供底部组件的显示/隐藏动画控制功能
 */
export function useBottomAnimation(isNearBottom: Ref<boolean>, isAtBottom: Ref<boolean>) {
  // 动画状态
  const isVisible = ref(false)
  const isAnimating = ref(false)
  const animationProgress = ref(0) // 0-1 的动画进度

  // 动画配置
  const ANIMATION_DURATION = 300 // 动画持续时间（毫秒）
  const ANIMATION_EASING = 'cubic-bezier(0.4, 0, 0.2, 1)' // 动画缓动函数

  let animationTimer: number | null = null
  let animationStartTime: number = 0

  /**
   * 启动显示动画
   */
  const startShowAnimation = () => {
    if (isVisible.value && !isAnimating.value) return

    isAnimating.value = true
    animationStartTime = performance.now()

    const animate = (currentTime: number) => {
      const elapsed = currentTime - animationStartTime
      const progress = Math.min(elapsed / ANIMATION_DURATION, 1)

      // 使用缓动函数计算动画进度
      animationProgress.value = easeInOutCubic(progress)

      if (progress < 1) {
        animationTimer = requestAnimationFrame(animate)
      } else {
        // 动画完成
        isVisible.value = true
        isAnimating.value = false
        animationProgress.value = 1
        animationTimer = null
      }
    }

    animationTimer = requestAnimationFrame(animate)
  }

  /**
   * 启动隐藏动画
   */
  const startHideAnimation = () => {
    if (!isVisible.value && !isAnimating.value) return

    isAnimating.value = true
    animationStartTime = performance.now()

    const animate = (currentTime: number) => {
      const elapsed = currentTime - animationStartTime
      const progress = Math.min(elapsed / ANIMATION_DURATION, 1)

      // 反向动画进度
      animationProgress.value = 1 - easeInOutCubic(progress)

      if (progress < 1) {
        animationTimer = requestAnimationFrame(animate)
      } else {
        // 动画完成
        isVisible.value = false
        isAnimating.value = false
        animationProgress.value = 0
        animationTimer = null
      }
    }

    animationTimer = requestAnimationFrame(animate)
  }

  /**
   * 停止当前动画
   */
  const stopAnimation = () => {
    if (animationTimer) {
      cancelAnimationFrame(animationTimer)
      animationTimer = null
      isAnimating.value = false
    }
  }

  /**
   * 缓动函数：ease-in-out-cubic
   */
  const easeInOutCubic = (t: number): number => {
    return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2
  }

  /**
   * 计算变换样式
   */
  const getTransformStyle = () => {
    const translateY = (1 - animationProgress.value) * 100 // 从下方滑入
    const opacity = animationProgress.value

    return {
      transform: `translateY(${translateY}%)`,
      opacity: opacity.toString(),
      transition: isAnimating.value ? 'none' : `all ${ANIMATION_DURATION}ms ${ANIMATION_EASING}`
    }
  }

  /**
   * 计算容器样式（用于页面内容的底部间距）
   */
  const getContainerStyle = () => {
    // 当底部组件显示时，为页面内容添加底部间距
    const paddingBottom = animationProgress.value * 80 // 80px 的底部间距

    return {
      paddingBottom: `${paddingBottom}px`,
      transition: isAnimating.value
        ? 'none'
        : `padding-bottom ${ANIMATION_DURATION}ms ${ANIMATION_EASING}`
    }
  }

  /**
   * 计算背景遮罩样式
   */
  const getOverlayStyle = () => {
    const opacity = animationProgress.value * 0.1 // 轻微的背景遮罩

    return {
      opacity: opacity.toString(),
      transition: isAnimating.value
        ? 'none'
        : `opacity ${ANIMATION_DURATION}ms ${ANIMATION_EASING}`,
      pointerEvents: animationProgress.value > 0 ? 'auto' : 'none'
    }
  }

  // 监听滚动状态变化，自动触发动画
  watch(
    [isNearBottom, isAtBottom],
    ([nearBottom, atBottom]) => {
      if (atBottom || nearBottom) {
        // 接近或到达底部时显示
        if (!isVisible.value && !isAnimating.value) {
          startShowAnimation()
        }
      } else {
        // 离开底部时隐藏
        if (isVisible.value && !isAnimating.value) {
          startHideAnimation()
        }
      }
    },
    { immediate: true }
  )

  // 计算属性
  const shouldShow = computed(() => isVisible.value || isAnimating.value)
  const animationState = computed(() => {
    if (!shouldShow.value) return 'hidden'
    if (isAnimating.value) return isVisible.value ? 'showing' : 'hiding'
    return 'visible'
  })

  /**
   * 手动控制显示/隐藏
   */
  const show = () => {
    stopAnimation()
    startShowAnimation()
  }

  const hide = () => {
    stopAnimation()
    startHideAnimation()
  }

  const toggle = () => {
    if (isVisible.value || (isAnimating.value && animationProgress.value > 0.5)) {
      hide()
    } else {
      show()
    }
  }

  /**
   * 立即设置状态（无动画）
   */
  const setVisible = (visible: boolean) => {
    stopAnimation()
    isVisible.value = visible
    animationProgress.value = visible ? 1 : 0
  }

  return {
    // 状态
    isVisible: readonly(isVisible),
    isAnimating: readonly(isAnimating),
    animationProgress: readonly(animationProgress),
    shouldShow,
    animationState,

    // 样式计算
    getTransformStyle,
    getContainerStyle,
    getOverlayStyle,

    // 控制方法
    show,
    hide,
    toggle,
    setVisible,
    stopAnimation
  }
}

// 导出类型定义
export type AnimationState = 'hidden' | 'showing' | 'hiding' | 'visible'
export type UseBottomAnimationReturn = ReturnType<typeof useBottomAnimation>
